package com.fawvw.digital.service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fawvw.digital.mapper.IPos;
import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.annotation.Resource;
import java.io.IOException;
@Component
public class CustomWebSocketHandler extends TextWebSocketHandler {

    private static final Logger log = LoggerFactory.getLogger(CustomWebSocketHandler.class);

    private JSONArray points;

    private volatile boolean pollingActive = false;

    private static final String PlcIp = "192.168.5.8";

    private static final S7PLC s7PLC = new S7PLC(EPlcType.S300, PlcIp);

    @Resource
    private IPos iPos;

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        JSONObject jsonObject = JSON.parseObject(message.getPayload());
        String flag = jsonObject.getString("flag");
        if(flag.equals("button")){
            JSONObject data = jsonObject.getJSONObject("data");
            sendToPlc(data);
        } else if (flag.equals("status")) {
            points = jsonObject.getJSONArray("data");
            if(!pollingActive){
                pollingActive = true;
                new Thread(() -> {
                    try {
                        while (session.isOpen()) {
                            JSONArray plcData = readPlc();
                            if (plcData != null && !plcData.isEmpty()) {
                                 session.sendMessage(new TextMessage(plcData.toJSONString()));
                            }
                            Thread.sleep(1000);
                        }
                    } catch (IOException | InterruptedException e) {
                        try {
                            session.close();
                        } catch (IOException ex) {
                            log.error("关闭ws异常", ex);
                        }
                    }
                }).start();
            }
        }
    }

    /**
     * 发送数据给PLC
     */
    public void sendToPlc(JSONObject data){
        log.info("发送给plc的数据:" + data);
        String address = data.getString("address");
        String type = data.getString("type");
        String value = data.getString("value");
        if (type.equals("Boolean")) {
            s7PLC.writeBoolean(address, Boolean.parseBoolean(value));
        } else {
            s7PLC.writeInt32(address, Integer.parseInt(value));
        }
    }

    /**
     * 读取PLC给前端
     */
    public JSONArray readPlc(){
        points.forEach(point -> {
            JSONObject jsonObject = (JSONObject) point;
            String address = jsonObject.getString("address");
            String type = jsonObject.getString("type");
            if (type.equals("Boolean")) {
                jsonObject.put("value", s7PLC.readBoolean(address));
            } else {
                iPos.insert(String.valueOf(s7PLC.readInt32(address)));
                jsonObject.put("value", s7PLC.readInt32(address));
            }
        });
        return points;
    }
}
